//
// Copyright (c) 2005, Robin Ward
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted 
// provided that the following conditions are met:
//
// Redistributions of source code must retain the above copyright notice, this list of conditions and the 
// following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 
// the following disclaimer in the documentation and/or other materials provided with the distribution.
//
// Neither the name of the Robotic Jelly nor the names of its contributors may be used to endorse or 
// promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
// POSSIBILITY OF SUCH DAMAGE.

#import "EditorView.h"
#import "Controller.h"

@implementation EditorView

- init
{
	self = [super init];
	
	background = nil;
	
	[self reset];
	return self;
}

- (void) reset
{
	currentOffset = 0;
	lastOffsetDisplayed = 0;

}

// Change the background image
- (void) setBackgroundImage: (NSImage *) back
{
	NSImage *newImage = [back retain];
    [background release];
    background = back;
	[self display];
}

- (void)drawRect:(NSRect)rect
{

	[[NSColor whiteColor] set];
	NSRectFill([self bounds]);


	if (background != nil)
	{
		[background dissolveToPoint:NSMakePoint(0,0) fraction:[controller opacity]];
	}
	
    NSBezierPath *myPath = [NSBezierPath bezierPath];

	NSDictionary *attribDict = [NSDictionary dictionaryWithObjectsAndKeys: 
			[controller previewColor], NSForegroundColorAttributeName,
			[controller previewFont], NSFontAttributeName, 
			nil];
	
	float mw = [controller marginWidth];
	NSRect margin = NSMakeRect(rect.origin.x + mw, rect.origin.y + mw, rect.size.width - (mw * 2), rect.size.height - (mw * 2) );
		
	int max_width = (rect.size.width - (mw * 2) - 1);
	
	// Try and get the first sentence
	if ([controller textContent] != NULL && [[controller textContent] length] > 0)
	{
		NSPoint renderAt = NSMakePoint(mw, mw);
	
		NSAttributedString *attribString = 
			[[NSAttributedString alloc] initWithString:[controller textContent] attributes:attribDict];
		
		NSString *attContent = [attribString string];
			
		unsigned int previousOffset = currentOffset;		
		unsigned int offset = currentOffset;

		while (margin.size.height > 0)
		{
			unsigned int indx = offset;
			unsigned int last_index = offset-1;
			unsigned int sentence_width = 0;
			
			NSAttributedString *sentence = nil;
			NSAttributedString *new_sentence = nil;
			
			bool broke_early = FALSE;
			NSRange range;
			
			range.location = NSNotFound;
			
			while ((indx != last_index) && (sentence_width <= max_width))
			{

				if (new_sentence != nil)
					sentence = [[NSAttributedString alloc] initWithString:[new_sentence string] attributes:attribDict];
				
				last_index = indx;

				
				indx = [attribString nextWordFromIndex:indx forward:YES];
				
				range = [attContent rangeOfString:@"\n" options:nil range:NSMakeRange(offset, MIN(indx-offset+1, [attContent length] - offset))];
								
				NSString *sub;
				
				if (range.location == NSNotFound)
				{
					if (offset != [attContent length])
					{
						sub = [attContent substringWithRange:NSMakeRange(offset, MIN(indx-offset+1,[attContent length]-offset))];
					} else {
						sub = @"";
						sentence_width = max_width + 1;
					}
					new_sentence = [[NSAttributedString alloc] initWithString:sub attributes:attribDict];
					sentence_width = [new_sentence size].width;
				} else {
				
					sub = [attContent substringWithRange:NSMakeRange(offset, (range.location-offset)-1)];
					
					sentence = [[NSAttributedString alloc] initWithString:sub attributes:attribDict];
					sentence_width = max_width+1;
				}
			}
			
			
			if (sentence != nil)
			{
				[sentence drawInRect:margin];
			}

			if ([sentence length] == 0)
			{
				margin.size.height -= [sentence size].height;
			}
			
			offset += [sentence length];
				
			if (offset < [attribString length])
			{
				unichar c = [attContent characterAtIndex:offset];
				while ([[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember:c])
				{
					offset++;
					
					if (offset >= [attContent length])
						break;
						
					if (c == '\n')
					{
						margin.size.height -= [sentence size].height;
					}
					
					c = [attContent characterAtIndex:offset];
				}
			}

			if (range.location == NSNotFound)
				margin.size.height -= [sentence size].height;
			
			if (margin.size.height <= [sentence size].height)
			{
				margin.size.height = 0;
			}
		}

		
		// Hack to flush to 100%
		if (previousOffset == offset)
		{
			offset = [attContent length];
		}

		lastOffsetDisplayed = offset;
		[attribString release];
	}
	


}

- (unsigned int) offsetDisplayed
{
	return lastOffsetDisplayed;
}

- (void) advancePage
{
	currentOffset = lastOffsetDisplayed;
}

- (void) dealloc
{
	[super dealloc];
}

@end
